"""
Pydantic schemas for data validation and response models
V3.0 Hardened version with strict validation
"""

from typing import Dict, Any, Optional, List
from pydantic import BaseModel, Field, validator
from datetime import datetime


class DetailedScores(BaseModel):
    """Detailed scoring information"""
    total: Dict[str, Any]
    vascular: Optional[Dict[str, Any]] = None
    bleeding: Optional[Dict[str, Any]] = None
    erosion: Optional[Dict[str, Any]] = None


class UCEISResponse(BaseModel):
    """Response model for UCEIS prediction results"""
    task_id: str = Field(..., description="Unique task identifier")
    uceis_score: int = Field(..., ge=0, le=8, description="UCEIS score (0-8)")
    severity: str = Field(..., description="Severity description")
    confidence: float = Field(..., ge=0.0, le=1.0, description="Confidence score")
    detailed_scores: DetailedScores = Field(..., description="Detailed scoring breakdown")
    processing_time: float = Field(..., ge=0.0, description="Processing time in seconds")
    success: bool = Field(True, description="Success status")
    message: str = Field(..., description="Status message")

    @validator('severity')
    def validate_severity(cls, v):
        """Validate severity value"""
        valid_severities = ['缓解期', '轻度', '中度', '重度', 'remission', 'mild', 'moderate', 'severe']
        if v not in valid_severities:
            raise ValueError(f'Severity must be one of: {valid_severities}')
        return v

    @validator('processing_time')
    def validate_processing_time(cls, v):
        """Validate processing time is reasonable"""
        if v > 60.0:  # More than 1 minute is unreasonable
            raise ValueError('Processing time exceeds reasonable limits')
        return round(v, 3)


class HealthResponse(BaseModel):
    """Response model for health check"""
    status: str = Field(..., description="Service status")
    message: str = Field(..., description="Status message")

    @validator('status')
    def validate_status(cls, v):
        """Validate status value"""
        if v not in ['healthy', 'unhealthy', 'degraded']:
            raise ValueError('Status must be healthy, unhealthy, or degraded')
        return v


class ErrorResponse(BaseModel):
    """Standardized error response"""
    success: bool = Field(False, description="Always false for errors")
    message: str = Field(..., description="Error message")
    error_code: Optional[str] = Field(None, description="Error code")
    details: Optional[Dict[str, Any]] = Field(None, description="Additional error details")
    timestamp: Optional[datetime] = Field(None, description="Error timestamp")


class ValidationErrorDetail(BaseModel):
    """Detailed validation error information"""
    field: str = Field(..., description="Field name")
    message: str = Field(..., description="Error message")
    value: Any = Field(..., description="Invalid value")


class ValidationErrorResponse(BaseModel):
    """Response for validation errors"""
    success: bool = Field(False, description="Always false for validation errors")
    message: str = Field("Validation failed", description="General error message")
    error_code: str = Field("VALIDATION_ERROR", description="Standard error code")
    details: List[ValidationErrorDetail] = Field(..., description="Detailed validation errors")
    timestamp: datetime = Field(default_factory=datetime.now, description="Error timestamp")


class RateLimitResponse(BaseModel):
    """Response for rate limit exceeded"""
    success: bool = Field(False, description="Always false for rate limit")
    message: str = Field("Rate limit exceeded", description="Error message")
    error_code: str = Field("RATE_LIMIT_EXCEEDED", description="Error code")
    retry_after: Optional[int] = Field(None, description="Seconds to wait before retry")
    limit: Optional[int] = Field(None, description="Request limit")
    remaining: Optional[int] = Field(None, description="Remaining requests")
    reset_time: Optional[datetime] = Field(None, description="Rate limit reset time")


class FileInfo(BaseModel):
    """File information metadata"""
    original_filename: str = Field(..., description="Original uploaded filename")
    secure_filename: str = Field(..., description="Sanitized filename")
    content_type: str = Field(..., description="MIME type")
    file_size: int = Field(..., ge=0, description="File size in bytes")
    file_hash: str = Field(..., description="SHA-256 hash")
    validation_passed: bool = Field(True, description="Validation status")

    @validator('file_size')
    def validate_file_size(cls, v):
        """Validate file size is reasonable"""
        if v > 100 * 1024 * 1024:  # 100MB
            raise ValueError('File size too large')
        return v

    @validator('file_hash')
    def validate_hash(cls, v):
        """Validate SHA-256 hash format"""
        if len(v) != 64:
            raise ValueError('Invalid hash format')
        try:
            int(v, 16)  # Validate hex format
        except ValueError:
            raise ValueError('Hash must be hexadecimal')
        return v


class ServerInfo(BaseModel):
    """Server information for monitoring"""
    version: str = Field("3.0.0", description="Server version")
    model_loaded: bool = Field(..., description="Whether model is loaded")
    uptime: Optional[float] = Field(None, description="Server uptime in seconds")
    memory_usage: Optional[Dict[str, float]] = Field(None, description="Memory usage info")
    request_count: Optional[int] = Field(None, description="Total request count")
    error_count: Optional[int] = Field(None, description="Total error count")

    class Config:
        schema_extra = {
            "example": {
                "version": "3.0.0",
                "model_loaded": True,
                "uptime": 3600.5,
                "memory_usage": {"used_mb": 2048, "available_mb": 6144},
                "request_count": 1250,
                "error_count": 3
            }
        }


# Export all schemas
__all__ = [
    'UCEISResponse',
    'HealthResponse',
    'ErrorResponse',
    'ValidationErrorResponse',
    'ValidationErrorDetail',
    'RateLimitResponse',
    'FileInfo',
    'ServerInfo',
    'DetailedScores'
]